package com.sxj.corejava.code15_反射;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class EmpFactoryMap {

    private static Map<String, String> map;

    static {
        map = new HashMap<>();
        try {
            // 通过IO流按行读取文件中的内容
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(
                            EmpFactoryMap
                                    .class
                                    .getClassLoader()
                                    .getResourceAsStream("emp.properties")));
            String line = null;
            while ((line = br.readLine()) != null) {
                // 在文件中,可能会出现空行
                // 因此,在处理时,只需要处理非空行的数据
                // 对于空行,直接无视即可
                if (!"".equals(line)) {
                    String[] arr = line.split("=");
                    map.put(arr[0], arr[1]);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Emp getEmp() {
        Class<Emp> c = Emp.class;
        try {
            // 创建员工对象
            Emp emp = c.newInstance();

            // 获取员工对象中所有的属性
            Field[] fields = c.getDeclaredFields();
            // 遍历这些属性
            for (Field field : fields) {
                // 通过@Value注解为每一个属性进行赋值
                // 获取当前属性上的注解
                Value annotation = field.getAnnotation(Value.class);
                System.out.println(annotation);
                // Value注解是为了给对应的属性赋值
                // 其值需要从emp.properties中根据key获取
                // 而注解的value属性的值对应的就是文件中的key
                // 因此,先获取到对应的key的值
                // 简单来讲,此处的key即为注解的值
                String key = annotation.value();
                // 根据key去Properties集合中取出对应的value
                String value = map.get(key);

                // 为属性赋值
                // 由于属性都是private修饰的,需要破坏封装原则
                field.setAccessible(true);
                field.set(emp, value);
            }
            return emp;
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }

}
